﻿using System.IO;

namespace TypeScriptJson.Generator
{
	public class TypeScriptCodeWriter
	{
		public TextWriter Writer { get; private set; }
		public int Depth { get; private set; }
		public string IndentString { get; set; }

		public TypeScriptCodeWriter(TextWriter writer)
		{
			Writer = writer;
			IndentString = DefaultIndentString;
		}

		public const string DefaultIndentString = "\t";

		public void Indent() { Depth++; }
		public void Unindent() { Depth--; }

		public void WriteStartModule(string moduleName)
		{
			WriteIndent();
			Writer.Write("module ");
			Writer.Write(moduleName);
			Writer.Write(" ");
			WriteStartBlock(isAtStartOfLine: false);
		}

		public void WriteEndModule()
		{
			WriteEndBlock();
		}

		public void WriteEndBlock(bool isAtStartOfLine = true, bool isEndOfLine = true, bool unindent = true)
		{
			if (unindent)
				Unindent();
			if (isAtStartOfLine)
				WriteIndent();
			Writer.Write("}");
			if (isEndOfLine)
				Writer.WriteLine();
		}

		public void WriteIndent()
		{
			var depth = Depth;
			while (depth-- > 0) Writer.Write(IndentString);
		}

		public void WriteStartBlock(bool isAtStartOfLine = true, bool isEndOfLine = true, bool indent = true)
		{
			if (isAtStartOfLine)
				WriteIndent();
			Writer.Write("{");
			if (isEndOfLine)
				Writer.WriteLine();
			if (indent)
				Indent();
		}

		public void WriteStartInterface(string name, bool export = false, string baseClassName = null, bool isAtStartOfLine = true)
		{
			WriteStartInterface(export, isAtStartOfLine);
			Writer.Write(name);
			Writer.Write(" ");
			if (baseClassName != null)
				Writer.Write("extends {0} ", baseClassName);
			WriteStartBlock(isAtStartOfLine: false);
		}

		public void WriteStartInterface(bool export = false, bool isAtStartOfLine = true, bool writeWhitespaceAfter = true)
		{
			if (isAtStartOfLine)
				WriteIndent();
			if (export)
				Writer.Write("export ");
			Writer.Write("interface");
			if (writeWhitespaceAfter)
				Writer.Write(" ");
		}

		public void WriteEndInterface()
		{
			WriteEndBlock();
		}

		public void WriteField(string propertyName, bool isOptional = false, string type = null, bool isAtSrartOfLine = true, bool isEndOfLine = true)
		{
			if (isAtSrartOfLine)
				WriteIndent();
			Writer.Write(propertyName);
			if (isOptional)
				Writer.Write("?");
			if (type != null)
			{
				Writer.Write(": ");
				Writer.Write(type);
			}
			Writer.Write(";");
			if (isEndOfLine)
				Writer.WriteLine();
		}

		public void WriteExtends(bool writeWhitespaceBefore = true, bool writeWhitespaceAfter = true)
		{
			if (writeWhitespaceBefore)
				Writer.Write(" ");
			Writer.Write("extends");
			if (writeWhitespaceAfter)
				Writer.Write(" ");
		}

		public void WriteStartField(string fieldName, bool isOptional = false, bool isAtStartOfLine = true)
		{
			if (isAtStartOfLine)
				WriteIndent();
			Writer.Write(fieldName);
			if (isOptional)
				Writer.Write("?");
		}
	}
}